/**
 * MIT License
 *
 * Copyright (c) 2020 deepstream.io
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * This file is modified
 * from [plugin.ts](https://github.com/deepstreamIO/deepstream.io-plugin-aws/blob/HEAD/src/plugin.ts)
 * in 2023-03-02.
 *
 * Copyright 2023 Huawei Cloud Computing Technologies Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { DeepstreamPlugin, DeepstreamServices, EVENT } from '@deepstream/types';
import OBSSync, { OBSSyncOptions } from './obs-sync';

export interface HuaweiCloudPluginOptions {
    accessKeyId: string,
    secretAccessKey: string,
    services: Array<{
        type: 'obs-sync',
        options: OBSSyncOptions
    }>
}

export default class HuaweiCloudPlugin extends DeepstreamPlugin {
    public description = 'Huawei Cloud Plugin';
    private logger = this.services.logger.getNameSpace('HUAWEI_CLOUD_PLUGIN');
    private plugins: DeepstreamPlugin[] = [];

    constructor(
        private options: HuaweiCloudPluginOptions,
        private services: Readonly<DeepstreamServices>,
    ) {
        super();
        this.options.services = this.options.services || [];
    }

    public init() {
        if (this.options.services.length === 0) {
            this.logger.fatal(EVENT.CONFIG_ERROR, 'No services defined for Huawei Cloud plugin');
        }
        this.plugins = this.options.services.map((service) => {
            switch (service.type) {
                case 'obs-sync':
                    return new OBSSync(service.options, this.services, {
                        secretAccessKey: this.options.secretAccessKey,
                        accessKeyId: this.options.accessKeyId,
                    });
                default:
                    this.logger.fatal(EVENT.CONFIG_ERROR, 'Invalid Huawei Cloud plugin config');
                    throw new Error(); // Needed to let typescript know app will have exited
            }
        });
        this.plugins.forEach((plugin) => plugin.init?.());
    }

    public async whenReady(): Promise<void> {
        const promises = this.plugins.map((plugin) => plugin.whenReady());
        await Promise.all(promises);
    }

    public async close(): Promise<void> {
        const promises = this.plugins.map((plugin) => plugin.close());
        await Promise.all(promises);
    }
}
